﻿/*
   Open Intel 
   Copyright © 2011 – ISC. All Rights Reserved.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Markup;
using ISC.MapDotNetServer.Common;

namespace OI.Framework
{
    // used to dynamically get data to a DataGrid or CSV file
    public class StringTable : Dictionary<int, StringRow>
    {
        public const string CsvRowSeparator = "\r\n";
        public const string CsvColumnSeparator = ",";
        public List<string> ColumnNames { get; set; }
        public Dictionary<string, string> HyperlinkColumnNames { get; set; }
        public bool IsUsedForPrintout { get; set; }

        public StringTable()
        {
            ColumnNames = new List<string>();
        }

        public StringTable(IEnumerable<string> columnNames)
        {
            ColumnNames = new List<string>();
            ColumnNames.AddRange(columnNames);
        }

        public StringTable(IEnumerable<string> columnNames, Dictionary<string, string> hyperlinkColumnNames, bool isUsedForPrintout)
        {
            ColumnNames = new List<string>();
            ColumnNames.AddRange(columnNames);

            HyperlinkColumnNames = hyperlinkColumnNames;
            IsUsedForPrintout = isUsedForPrintout;
        }

        public void AddColumn(string columnName)
        {
            ColumnNames.Add(columnName);
        }

        public void AddRow(IEnumerable<string> columnValues)
        {
            AddRow(columnValues, null);
        }

        public void AddRow(IEnumerable<string> columnValues, Shape shape)
        {
            var sr = new StringRow {Shape = shape};
            Add(Count, sr);
            ResetRowValues(Count - 1, columnValues);
        }

        public StringRow NewRow()
        {
            var row = new StringRow();
            foreach (string columnName in ColumnNames)
            {
                row.Add(columnName, string.Empty);
            }
            return (row);
        }

        public void ResetRowValues(int rowIndex, IEnumerable<string> columnValues)
        {
            this[rowIndex].Clear();
            foreach (string columnName in ColumnNames)
            {
                var enumerable = columnValues as string[] ?? columnValues.ToArray();
                this[rowIndex].Add(columnName, enumerable.ElementAt(ColumnNames.IndexOf(columnName)));
            }
        }

        public void SaveAsCsv(string path)
        {
            TextWriter writer = new StreamWriter(path);

            //write header (column names)
            writer.WriteLine(string.Join(CsvColumnSeparator, ColumnNames.ToArray()));

            //write all rows
            foreach (int rowNumber in Keys)
            {
                string[] recordValues = (from value in this[rowNumber].Values
                                         select "\"" + value + "\"").ToArray();
                writer.WriteLine(string.Join(CsvColumnSeparator, recordValues));
            }

            writer.Close();
        }

        public void BindStringTableToDataGrid(DataGrid dataGrid)
        {
            dataGrid.AutoGenerateColumns = false;

            dataGrid.Columns.Clear();
            foreach (string columnName in ColumnNames)
            {
                // see if this column is a hyperlink column
                if (HyperlinkColumnNames != null && 
                    HyperlinkColumnNames.ContainsKey(columnName))
                {
                    // ignore hyperlink columns in printouts
                    if (!IsUsedForPrintout)
                    {
                        var hlString =
                            "<DataTemplate xmlns='http://schemas.microsoft.com/client/2007' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>" +
                                "<HyperlinkButton Margin='4' NavigateUri='{Binding Path=., Converter={StaticResource ColumnValueSelector}, ConverterParameter=" +
                                columnName +
                                "}' TargetName='_blank' Content='" +
                                HyperlinkColumnNames[columnName] +
                                "'></HyperlinkButton>" +
                            "</DataTemplate>";

                        var hyperlinkCol = new DataGridTemplateColumn()
                        {
                            Header = columnName,
                            CanUserSort = true,
                            SortMemberPath = "[" + columnName + "]",
                            CellTemplate = (System.Windows.DataTemplate)XamlReader.Load(hlString)
                        };

                        dataGrid.Columns.Add(hyperlinkCol);
                    }
                }
                else
                {
                    var textColumn = new DataGridTextColumn
                    {
                        Header = columnName,
                        Binding = new Binding { Converter = new ColumnValueSelector(), ConverterParameter = columnName },
                        CanUserSort = true,
                        SortMemberPath = "[" + columnName + "]"
                    };

                    dataGrid.Columns.Add(textColumn);   
                }
            }

            dataGrid.ItemsSource = Values;
        }
    }


    public class StringRow : Dictionary<string, string>
    {
        public Shape Shape { set; get; }
    }


    public class ColumnValueSelector : IValueConverter
    {
        #region IValueConverter Members

        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var row = (StringRow) value;
            var columnName = (string) parameter;
            return (row[columnName]);
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }
}